package com.jarveis.frame.task;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Iterator;
import java.util.List;

import org.apache.log4j.Logger;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.parser.Parser;

import com.jarveis.frame.io.Resource;
import com.jarveis.frame.lang.CharacterUtil;
import com.jarveis.frame.lang.StringUtil;

/**
 * 计划后台程序
 * 
 * @author liuguojun
 */
public class TaskDaemon extends Thread {

	private static final Logger logger = Logger.getLogger(TaskDaemon.class);

	private TaskPool taskPool = null;
	private List<ITask> tasks = new ArrayList<ITask>();

	public TaskDaemon() {
		this("config.xml");
	}

	public TaskDaemon(String filePath) {
		try {
			init(filePath);
		} catch (Exception ex) {
			logger.error(ex.getMessage(), ex);
		}
	}

	/**
	 * 初始化操作
	 * 
	 * @param filePath
	 * @throws Exception
	 */
	private void init(String filePath) throws Exception {
		// 读取配置文件
		Document document = Jsoup.parse(Resource.getStream(filePath),
				CharacterUtil.UTF8, "", Parser.xmlParser());

		this.initTaskPool(document);
		this.initTasks(document);
	}

	/**
	 * 初始化任务池
	 * 
	 * @param document
	 * @throws Exception
	 */
	private void initTaskPool(Document document) throws Exception {
		int minSize = 5, maxSize = 100;
		List pps = document.select("taskConfig > taskPool > property");
		for (Iterator it = pps.iterator(); it.hasNext();) {
			Element pp = (Element) it.next();
			String name = pp.attr("name");
			String value = pp.attr("value");
			if ("minSize".equals(name)) {
				minSize = Integer.parseInt(value, 10);
			} else if ("maxSize".equals(name)) {
				maxSize = Integer.parseInt(value, 10);
			}
		}
		taskPool = TaskPool.getInstance(minSize, maxSize);
	}

	/**
	 * 初始化任务
	 * 
	 * @param document
	 * @throws Exception
	 */
	private void initTasks(Document document) throws Exception {
		List ts = document.select("taskConfig > tasks > task");
		for (Iterator it = ts.iterator(); it.hasNext();) {
			try {
				Element t = (Element) it.next();
				TaskInfo taskInfo = new TaskInfo();
				taskInfo.setCode(t.attr("code"));
				taskInfo.setSleepTime(t.attr("time")); // 设置暂停时间
				taskInfo.setStatus(ITask.Status.Sleep); // 初始化任务执行状态
				taskInfo.setRunTime(0L); // 初始化执行时间

				String clazz = t.attr("class");
				if (StringUtil.isEmpty(clazz)) {
					continue;
				}

				Object object = (Object) Class.forName(clazz).newInstance();
				ITask task = null;
				if (object instanceof ITask) {
					task = (ITask) object;
					task.setTaskInfo(taskInfo);
				} else {
					continue;
				}

				addTask(task);

				logger.info("加载 (" + clazz + ") 任务成功！");
			} catch (Exception ex) {
				logger.error(ex.getMessage(), ex);
			}
		}
	}
	
	public void addTask(ITask task){
		if (task != null && task.getTaskInfo() != null) {
			tasks.add(task);
		}
	}

	public void run() {
		while (true) {
			// 获取当前时间
			long nowTime = Calendar.getInstance().getTimeInMillis();

			for (ITask task : tasks) {
				if (task.getTaskInfo().getStatus() == ITask.Status.Start
						|| task.getTaskInfo().getStatus() == ITask.Status.Stop) {
					continue;
				}

				long runTime = task.getTaskInfo().getRunTime();
				if (runTime == 0L) {
					taskPool.runTask(task);
				} else if (runTime > 0L && nowTime > runTime) {
					taskPool.runTask(task);
				} else {
					continue;
				}
			}

			try {
				Thread.sleep(1000);
			} catch (InterruptedException ex) {
				logger.error("后台任务调试线程休眠被异常中断", ex);
			}
		}
	}
}
